package com.yanqu.road.server.gameplayer.module.activity.zhenhuan;

import com.yanqu.road.dao.impl.player.UserZhenHuanFirstDaoImpl;
import com.yanqu.road.entity.activity.zhenhuan.firstProcess.UserZhenHuanFirstProcessData;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanConcubineConfig;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanStoryConfig;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogZhenHuanFirstChose;
import com.yanqu.road.logic.activity.zhenhuan.ZhenHuanFirstProcessConfig;
import com.yanqu.road.logic.helper.CalcPowerResult;
import com.yanqu.road.logic.helper.PowerHelper;
import com.yanqu.road.pb.activity.ZhenHuanProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityWorshipModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.zhenhuan.ZhenHuanConfigMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.logic.activity.zhenhuan.ZhenHuanPb;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class ZhenHuanFirstProcessModule extends GeneralModule {
    public ZhenHuanFirstProcessModule(GamePlayer player) {
        super(player);
    }

    private UserZhenHuanFirstProcessData userData;

    @Override
    public boolean loadData() {
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        if (config == null) {
            return true;
        }
        userData = new UserZhenHuanFirstDaoImpl().getUserZhenHuanFirstProcessData(config.getActivityId(), getUserId());
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                new UserZhenHuanFirstDaoImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new UserZhenHuanFirstDaoImpl().update(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        initUserData();
        syncConfig();
        syncUserData();

//        if (userData != null) {
//            player.notifyListener(eGamePlayerEventType.ZhenHuanFirstProcessRank.getValue(), userData.getScore());
//        }
    }

    public void iniSystem() {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.ZhenHuanFirstProcess.getValue())) {
            return;
        }
        initUserData();
        syncConfig();
        syncUserData();
    }

    public void initUserData() {
        if (!SystemOpenMgr.systemOpen(player, eSystemId.ZhenHuanFirstProcess.getValue())) {
            return;
        }
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        if (config == null) {
            return;
        }
        if (userData == null || userData.getActivityId() != config.getActivityId()) {
            userData = new UserZhenHuanFirstProcessData(config.getActivityId(), getUserId());
            userData.setPower(config.getInitPower());
        }
    }

    public void syncConfig() {
        if (userData == null) {
            return;
        }
        ZhenHuanProto.ZhenHuanFirstProcessConfigSyncMsg configMsg = ZhenHuanConfigMgr.getFirstProcessConfigMsg(player.getLanguage());
        if (configMsg == null) {
            return;
        }
        player.sendPacket(ClientProtocol.U_ZHENHUAN_FIRST_PROCESS_CONFIG_SYNC, configMsg.toBuilder());
    }

    public void syncUserData() {
        if (userData == null) {
            return;
        }
        ZhenHuanProto.ZhenHuanFirstProcessUserSyncMsg.Builder syncMsg = ZhenHuanPb.parseUserMsg(userData);
        syncMsg.setIsWorship(player.getModule(ActivityWorshipModule.class).isWorship(userData.getActivityId()));
        syncMsg.setPower(getNowPower());
        player.sendPacket(ClientProtocol.U_ZHENHUAN_FIRST_PROCESS_USER_SYNC, syncMsg);
    }

    public int getMainScene() {
        if (userData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_NOT_OPEN;
        }
        long nextPowerTime = calcNextPowerTime();

        if (userData.getStoryId() == 0){
            //随机一个故事
            int storyId = config.randomStoryId();
            ZhenHuanStoryConfig storyConfig = config.getStoryConfig(storyId);
            if (storyConfig == null) {
                return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_STORY_NOT_FOUND;
            }
            userData.setStoryId(storyId);
            userData.setChoseMap(new ConcurrentHashMap<>());
        }

        ZhenHuanProto.ZhenHuanFirstProcessMainSceneRespMsg.Builder builder = ZhenHuanProto.ZhenHuanFirstProcessMainSceneRespMsg.newBuilder();
        builder.setRet(0);
        builder.setActivityId(config.getActivityId());
        builder.setScore(userData.getScore());
        builder.setPower(getNowPower());
        builder.setNextPowerTime(nextPowerTime);
        builder.setStoryId(userData.getStoryId());
        for (Map.Entry<Integer, Integer> entry : userData.getChoseMap().entrySet()) {
            Integer pos = entry.getKey();
            int concubineId = entry.getValue();
            ZhenHuanProto.ZhenHuanFirstProcessConcubineTemp.Builder temp = ZhenHuanProto.ZhenHuanFirstProcessConcubineTemp.newBuilder();
            temp.setPos(pos);
            temp.setConcubineId(concubineId);
            builder.addConcubineList(temp);
        }
        player.sendPacket(ClientProtocol.U_ZHENHUAN_FIRST_PROCESS_MAIN_SCENE, builder);
        return 0;
    }

    public long calcNextPowerTime() {
        if (userData == null) {
            return -1;
        }
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        if (config == null) {
            return -1;
        }

        if (userData.getPower() >= config.getInitPower()) {
            return 0;
        }

        long powerRecoverCD = config.getPowerRecoverCD(); // 恢复一点体力的时间秒
        long powerRecoverTime = userData.getPowerRecoverTime() / 1000; // 上次恢复体力的时间 秒
        CalcPowerResult calcPowerResult = PowerHelper.calcPower(powerRecoverTime, powerRecoverCD, 1, config.getInitPower(), userData.getPower());
        userData.setPower(calcPowerResult.getCurPower());
        userData.setPowerRecoverTime(calcPowerResult.getLastRecoverTime() * 1000);

        return userData.getPowerRecoverTime() + powerRecoverCD * 1000;
    }

    public int choseConcubine(int pos) {
        if (userData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_NOT_OPEN;
        }

        if (pos <= 0 || pos > config.getConcubineMaxNum()) {
            return GameErrorCode.E_ERROR_DATA;
        }

        if (userData.getChoseMap().containsKey(pos)) {
            return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_POS_REPEAT;
        }
        int nowPower = getNowPower();
        if (nowPower < config.getChoseCost()) {
            return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_POWER_NOT_ENOUGH;
        }

        if (userData.getStoryId() == 0) {
            return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_STORY_NOT_FOUND;
        }

        ZhenHuanStoryConfig storyConfig = config.getStoryConfig(userData.getStoryId());
        if (storyConfig == null) {
            userData.setStoryId(0); //防止卡住
            userData.setChoseMap(new ConcurrentHashMap<>());
            return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_STORY_NOT_FOUND;
        }

        boolean isSpecial = false;
        if (userData.getChoseMap().isEmpty()) {
            //每个故事首次选妃,判断是否触发特效
            if (config.getGuaranteeNum() > 0 && userData.getSpecialAmount() >= config.getGuaranteeNum()) {
                isSpecial = true;
            } else {
                isSpecial = config.randomSpecialEffect(getUnlockAmount());
            }
        }

        Set<Integer> concubineSet = storyConfig.getConcubineSet();
        for (Integer concubineId : userData.getChoseMap().values()) {
            concubineSet.remove(concubineId);
        }

        ZhenHuanProto.ZhenHuanFirstProcessChoseRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanFirstProcessChoseRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setActivityId(config.getActivityId());

        List<Integer> openConcubineList = new ArrayList<>();
        int oldScore = userData.getScore();
        if (isSpecial) {//特殊效果,把整个故事的选妃全开,除了第一个位置其他位置随机
            respMsg.setIsSpecial(true);

            int scoreAdd = 0;

            List<Integer> concubineList = new ArrayList<>(concubineSet);
            List<Integer> posList = config.randomPosList(concubineList.size(), pos);
            Map<Integer, Integer> posConcubineMap = new ConcurrentHashMap<>();
            posConcubineMap.put(pos, concubineList.get(0));
            ZhenHuanConcubineConfig firstConcubineConfig = config.getConcubineConfig(concubineList.get(0));
            if (firstConcubineConfig == null) {
                return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_CONCUBINE_NOT_FOUND;
            }
            scoreAdd += firstConcubineConfig.getScore();
            openConcubineList.add(firstConcubineConfig.getId());

            for (int i = 0; i < posList.size() && i + 1 < concubineList.size(); i++) {
                Integer concubineId = concubineList.get(i + 1);
                ZhenHuanConcubineConfig concubineConfig = config.getConcubineConfig(concubineId);
                if (concubineConfig == null) {
                    return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_CONCUBINE_NOT_FOUND;
                }
                posConcubineMap.put(posList.get(i), concubineList.get(i + 1));
                scoreAdd += concubineConfig.getScore();
                openConcubineList.add(concubineConfig.getId());
            }
            usePower(config.getChoseCost());
            userData.setChoseMap(posConcubineMap);

            Property reward = new Property(config.getExchangeGoodsId(), scoreAdd);
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.ZhenHuanFirstProcess, eLogMoneyType.ZhenHuanFirstProcessReward);
            userData.setScore(userData.getScore() + scoreAdd);
            concubineSet.clear();
        } else {
            if (!concubineSet.isEmpty()) {
                //随机一个
                Integer concubineId = concubineSet.stream()
                        .skip(new Random().nextInt(concubineSet.size()))
                        .findFirst()
                        .orElse(null); // 如果HashSet为空，返回null
                ZhenHuanConcubineConfig concubineConfig = config.getConcubineConfig(concubineId);
                if (concubineConfig == null) {
                    return GameErrorCode.E_ZHENHUAN_FIRST_PROCESS_CONCUBINE_NOT_FOUND;
                }

                usePower(config.getChoseCost());
                userData.putChoseMap(pos, concubineId);
                openConcubineList.add(concubineId);

                int score = concubineConfig.getScore();
                Property reward = new Property(config.getExchangeGoodsId(), score);
                player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.ZhenHuanFirstProcess, eLogMoneyType.ZhenHuanFirstProcessReward);
                userData.setScore(userData.getScore() + score);

                concubineSet.remove(concubineId);

                respMsg.setChoseReward(PropertyHelper.parsePropertyToString(reward));
            }
        }

        player.notifyListener(eGamePlayerEventType.ZhenHuanFirstProcessRank.getValue(), userData.getScore());

        if (concubineSet.isEmpty()) {
            //故事结束,获得额外奖励,并重置
            Property storyReward = PropertyHelper.randomPropertyByListList(storyConfig.getRewardList());
            player.getModule(CurrencyModule.class).addCurrency(storyReward, eLogMoneyType.ZhenHuanFirstProcess, eLogMoneyType.ZhenHuanFirstProcessStoryReward);

            Integer oldNum = userData.getUnlockStory().getOrDefault(userData.getStoryId(), 0);
            if (oldNum == 0) {//首次解锁,获得首次解锁奖励
                Property firstReward = PropertyHelper.parseStringToProperty(storyConfig.getFirstUnlockReward());
                player.getModule(CurrencyModule.class).addCurrency(firstReward, eLogMoneyType.ZhenHuanFirstProcess, eLogMoneyType.ZhenHuanFirstProcessFirstUnlockReward);
                respMsg.setFirstUnlockReward(storyConfig.getFirstUnlockReward());
            }

            respMsg.setStoryId(userData.getStoryId());
            respMsg.setStoryReward(PropertyHelper.parsePropertyToString(storyReward));

            userData.addUnlockStory(userData.getStoryId());
            userData.setStoryId(0);

            player.notifyListener(eGamePlayerEventType.ZhenHuanFirstProcessUnlockStoryNum.getValue(), 1);

            if (isSpecial) {//保底累计清空
                userData.setSpecialAmount(0);
            }
        }

        syncUserData();

        long nextPowerTime = calcNextPowerTime();

        respMsg.setScore(userData.getScore());
        respMsg.setPower(getNowPower());
        respMsg.setNextPowerTime(nextPowerTime);
        for (Map.Entry<Integer, Integer> entry : userData.getChoseMap().entrySet()) {
            ZhenHuanProto.ZhenHuanFirstProcessConcubineTemp.Builder temp = ZhenHuanProto.ZhenHuanFirstProcessConcubineTemp.newBuilder();
            temp.setPos(entry.getKey());
            temp.setConcubineId(entry.getValue());
            respMsg.addConcubineList(temp);
        }
        Integer storyAmount = userData.getUnlockStory().getOrDefault(respMsg.getStoryId(), 0);
        respMsg.setStoryAmount(storyAmount);
        player.sendPacket(ClientProtocol.U_ZHENHUAN_FIRST_PROCESS_CHOSE, respMsg);
        AutoLogMgr.add(new LogZhenHuanFirstChose(config.getActivityId(), getUserId(), nowPower, pos, isSpecial, openConcubineList,
                respMsg.getStoryId(), userData.getScore() - oldScore, respMsg.getChoseReward(), respMsg.getStoryReward(), respMsg.getFirstUnlockReward()));

        //发到跨服激活一下晋升功能
        player.sendPacket(CrossProtocol.C_CROSS_ZHENHUAN_FIRST_PROCESS_PROMOTION_ACTIVITY, ZhenHuanProto.ZhenHuanSecondProcessGetNewKickRecordReqMsg.newBuilder().setActivityId(userData.getActivityId()));
        return 0;
    }

    public int getNowPower() {
        long ret = calcNextPowerTime();
        if (ret == -1) {
            return 0;
        }
        return userData.getPower();
    }

    public void addPower(int power) {
        long ret = calcNextPowerTime();
        if (ret == -1) {
            return;
        }
        userData.setPower(userData.getPower() + power);
        syncUserData();
    }

    public void usePower(int power) {
        long ret = calcNextPowerTime();
        if (ret == -1) {
            return;
        }
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        int maxPower = config.getInitPower();
        int oldPower = userData.getPower();
        userData.setPower(userData.getPower() - power);
        if (oldPower >= maxPower && userData.getPower() < maxPower) {
            userData.setPowerRecoverTime(DateHelper.getCurrentTime());
        }
    }

    public int getUnlockStoryList() {
        if (userData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        ZhenHuanFirstProcessConfig config = ZhenHuanConfigMgr.getFirstProcessConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        ZhenHuanProto.ZhenHuanFirstProcessHistoryStoryRespMsg.Builder respMsg = ZhenHuanProto.ZhenHuanFirstProcessHistoryStoryRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setActivityId(config.getActivityId());
        for (Map.Entry<Integer, Integer> entry : userData.getUnlockStory().entrySet()) {
            Integer storyId = entry.getKey();
            Integer num = entry.getValue();
            ZhenHuanProto.ZhenHuanFirstProcessHistoryStoryTemp.Builder temp = ZhenHuanProto.ZhenHuanFirstProcessHistoryStoryTemp.newBuilder();
            temp.setStoryId(storyId);
            temp.setNum(num);
            respMsg.addUnlockStory(temp);
        }
        player.sendPacket(ClientProtocol.U_ZHENHUAN_FIRST_PROCESS_HISTORY_STORY, respMsg);

        return 0;
    }

    public int getUnlockAmount() {
        if (userData == null) {
            return 0;
        }
        int totalAmount = 0;
        for (Integer amount : userData.getUnlockStory().values()) {
            totalAmount += amount;
        }
        return totalAmount;
    }
}
